package com.umeox.moto.watch.themes.widget.loader;

import android.animation.ValueAnimator;
import android.graphics.Canvas;
import android.graphics.Paint;

import java.util.ArrayList;

public class BallSpinFadeLoaderIndicator extends Indicator {
    public static final int DURATION_IN_MILLIS = 800;
    public static final float MAX_SCALE = 1.0f, MIN_SCALE = 0.4f;
    public static final int MAX_ALPHA = 255, MIN_ALPHA = 77;

    public static int ELEMENT_COUNT = 10;
    public static float[] scaleFloats = new float[ELEMENT_COUNT];
    public static int[] alphas = new int[ELEMENT_COUNT];

    static {
        for (int i = 0; i < ELEMENT_COUNT; i++) {
            float fraction = ((float) DURATION_IN_MILLIS / (ELEMENT_COUNT - 1)) * i / DURATION_IN_MILLIS;
            float scale = (MIN_SCALE + (fraction * (MAX_SCALE - MIN_SCALE)));
            int alpha = (int) (MIN_ALPHA + (fraction * (MAX_ALPHA - MIN_ALPHA)));
            scaleFloats[i] = scale;
            alphas[i] = alpha;
        }
    }

    @Override
    public void draw(Canvas canvas, Paint paint) {
        float radius = getWidth() / 10;
        for (int i = 0; i < ELEMENT_COUNT; i++) {
            canvas.save();
            Point point = circleAt(getWidth(), getHeight(), getWidth() / 2 - radius, i * (Math.PI / 4));
            canvas.translate(point.x, point.y);
            canvas.scale(scaleFloats[i], scaleFloats[i]);
            paint.setAlpha(alphas[i]);
            canvas.drawCircle(0, 0, radius, paint);
            canvas.restore();
        }
    }

    @Override
    public ArrayList<ValueAnimator> onCreateAnimators() {
        ArrayList<ValueAnimator> animators = new ArrayList<>();
        int delay = 0;
        for (int i = 0; i < ELEMENT_COUNT; i++) {
            final int index = i;
            ValueAnimator scaleAnim = ValueAnimator.ofFloat(MAX_SCALE, MIN_SCALE, MAX_SCALE);
            scaleAnim.setDuration(DURATION_IN_MILLIS);
            scaleAnim.setRepeatCount(-1);
            scaleAnim.setStartDelay(delay);
            addUpdateListener(scaleAnim, animation -> {
                scaleFloats[index] = (float) animation.getAnimatedValue();
                postInvalidate();
            });

            ValueAnimator alphaAnim = ValueAnimator.ofInt(MAX_ALPHA, MIN_ALPHA, MAX_ALPHA);
            alphaAnim.setDuration(DURATION_IN_MILLIS);
            alphaAnim.setRepeatCount(-1);
            alphaAnim.setStartDelay(delay);
            addUpdateListener(alphaAnim, animation -> {
                alphas[index] = (int) animation.getAnimatedValue();
                postInvalidate();
            });
            animators.add(scaleAnim);
            animators.add(alphaAnim);
            delay += DURATION_IN_MILLIS / ELEMENT_COUNT;
        }
        return animators;
    }

    /**
     * 圆O的圆心为(a,b),半径为R,点A与到X轴的为角α.
     * 则点A的坐标为(a+R*cosα,b+R*sinα)
     *
     * @param width
     * @param height
     * @param radius
     * @param angle
     * @return
     */
    Point circleAt(int width, int height, float radius, double angle) {
        float x = (float) (width / 2 + radius * (Math.cos(angle)));
        float y = (float) (height / 2 + radius * (Math.sin(angle)));
        return new Point(x, y);
    }

    final class Point {
        public float x;
        public float y;

        public Point(float x, float y) {
            this.x = x;
            this.y = y;
        }
    }
}
